﻿using Microsoft.Data.Sqlite;
using Super.Hmi.Entities;
using System.Linq.Expressions;

namespace Super.Hmi.IServices
{
    /// <summary>
    /// 基础服务接口类
    /// </summary>
    public interface IBaseService
    {
        #region Query
        /// <summary>
        /// 根据id查询实体 主键查询
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>实体</returns>
        T Find<T>(params object?[]? keyValues) where T : class;
        /// <summary>
        /// 提供对单表的查询
        /// </summary>
        /// <returns>IQueryable类型集合</returns>
        [Obsolete("尽量避免使用，using 带表达式目录树的 代替")]
        IQueryable<T> Set<T>() where T : class;
        /// <summary>
        /// 查询
        /// </summary>
        /// <typeparam name="T">实体</typeparam>
        /// <param name="funcWhere">查询条件</param>
        /// <returns>IQueryable类型集合</returns>
        IQueryable<T> Query<T>(Expression<Func<T, bool>> funcWhere) where T : class;
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <typeparam name="S">排序的字段类型</typeparam>
        /// <param name="funcWhere">筛选方法</param>
        /// <param name="pageSize">一页的数量</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="funcOrderby">排序方法</param>
        /// <param name="isAsc">是否正序</param>
        /// <returns>分页查询结果</returns>
        PageResult<T> QueryPage<T, S>(Expression<Func<T, bool>> funcWhere, int pageSize, int pageIndex, Expression<Func<T, S>> funcOrderby, bool isAsc = true, params Func<IQueryable<T>, IQueryable<T>>[] loadNavigations) where T : class;
        #endregion

        #region Insert
        /// <summary>
        /// 新增数据，即时Commit
        /// </summary>
        /// <param name="t"></param>
        /// <returns>返回带主键的实体</returns>
        T Insert<T>(T t) where T : class;
        /// <summary>
        /// 新增数据，即时Commit
        /// 多条sql 一个连接，事务插入
        /// </summary>
        /// <param name="tList">插入的集合</param>
        IEnumerable<T> Insert<T>(IEnumerable<T> tList) where T : class;
        #endregion

        #region Update
        /// <summary>
        /// 更新数据，即时Commit
        /// </summary>
        /// <param name="t">修改的实体</param>
        void Update<T>(T t) where T : class;
        /// <summary>
        /// 更新数据，即时Commit
        /// </summary>
        /// <param name="tList">修改的整体集合</param>
        void Update<T>(IEnumerable<T> tList) where T : class;
        #endregion

        #region Delete
        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <typeparam name="T">实体</typeparam>
        /// <param name="keyValues">删除主键</param>
        void Delete<T>(params object?[]? keyValues) where T : class;
        /// <summary>
        /// 批量多主键删除
        /// </summary>
        /// <typeparam name="T">实体</typeparam>
        /// <param name="keyValues">多主键</param>
        void Deletes<T>(IEnumerable<object[]> keyValues) where T : class;
        /// <summary>
        /// 批量单主键删除
        /// </summary>
        /// <typeparam name="T">实体</typeparam>
        /// <typeparam name="TId">删除的ID类型</typeparam>
        /// <param name="keyValues">主键</param>
        void Deletes<T, TId>(IEnumerable<TId> keyValues) where T : class;
        #endregion

        #region Other
        /// <summary>
        /// 立即保存全部修改
        /// 把增/删的savechange给放到这里，是为了保证事务的
        /// </summary>
        void Commit();
        /// <summary>
        /// 执行sql 返回集合
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        IQueryable<T> ExcuteQuery<T>(string sql, SqliteParameter[] parameters) where T : class;
        /// <summary>
        /// 执行sql，无返回
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <param name="parameters"></param>
        void Excute<T>(string sql, SqliteParameter[] parameters) where T : class;

        #endregion

    }
}
